/* 
 * File:   main.c
 * Author: gaurav
 *
 * Created on 1 January, 2011, 11:50 AM
 */

 
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>

#include "tftp.h"


int t_s,s_l;
_Bool flag=1;

//struct sockaddr_in cl_addr;

void ctrl_c(int signum)
{
    flag=0;
    close(t_s);
    exit(-1);
}




void alarm_handler(int signum)
{
    int pid,ctr=0;
    while((pid=waitpid(-1,0,WNOHANG))!=-1)
    {
        if(pid==0)
            break;
      //  printf("\n chld %d ended",pid);
        ctr++;
    }
//    printf("\n %d chlds ended..",ctr);
    fflush(stdout);
}




void do_write_thread(struct sockaddr_in cl_addr,char *file,int s_l)
{

    struct _DATA_CAMINFO *data_caminf;
    pthread_t thread1;
    int  iret1;

    data_caminf = malloc(sizeof(struct _DATA_CAMINFO));
    data_caminf->s_l = s_l;
    data_caminf->file = file;
    memcpy(&(data_caminf->cl_addr),&cl_addr,sizeof(struct sockaddr_in));
    
    print_socket(cl_addr);

    
    iret1 = pthread_create( &thread1, NULL, thd_caminfo, (void*) data_caminf);
//    pthread_join( thread1, NULL);
}






int main(int argc, char** argv)
{
    int i,res,fd,oc;
    struct sockaddr_in myaddr,cl_addr;
    struct itimerval delay;
    short opcode;
    char buf[512],req_file[30];

    signal(SIGINT,ctrl_c);
    signal (SIGALRM, alarm_handler);
    delay.it_value.tv_sec=0;
    delay.it_value.tv_usec=1000;
    delay.it_interval.tv_sec=30;
    delay.it_interval.tv_usec=1000;
    if(setitimer (ITIMER_REAL, &delay, NULL)==-1)
    {
        perror("timer prob");
        return -1;
    }
    t_s= socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    if(t_s==-1)
    {
        perror("sock");
        return -1;
    }

    memset(&myaddr,0,sizeof(myaddr));
    myaddr.sin_family=AF_INET;
    myaddr.sin_port=htons(69);
    myaddr.sin_addr.s_addr=htonl(INADDR_ANY);

    if(bind(t_s,(struct sockaddr*)&myaddr,sizeof(myaddr))==-1)
    {
        perror("bind..");
        return -1;
    }

//    init_thread();


    while(flag)
    {

        printf("\n listening...\n");
        fflush(stdout);
        s_l=sizeof(cl_addr);
        memset(buf,0,512);

        if((res=recvfrom(t_s,buf,512,0,&cl_addr,&s_l))==-1)
        {
            perror("\n recv");
            return -1;
        }



        
        opcode=GetShortAt(buf);
        printf("oc = %i \n",opcode);

        strcpy(req_file,buf+2);
        printf("%s \n",req_file);

        //printf("\n\n %s %d",cl_addr.sa_data,cl_addr.sa_family);
        oc=opcode;
        switch(oc)
        {
            case RRQ:
                //do_write(cl_addr,req_file,s_l);
                do_write_thread(cl_addr,req_file,s_l);
                break;
            case WRQ:   
                do_read(cl_addr,req_file,s_l);
                //read_from_remote(cl_addr,req_file);
                break;
            default:
                break;
        }

    }
    if(close(t_s)==-1)
        perror("cls");
    

    return (EXIT_SUCCESS);
}



